package smecta.client.print.controller;

import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import smecta.client.print.domain.ScpCodeFormModel;
import smecta.client.print.domain.ScpDataAcqModel;
import smecta.client.print.domain.ScpPackage;
import smecta.client.print.domain.SysReport;
import smecta.client.print.domain.query.PageDTO;
import smecta.client.print.domain.query.ReportQuery;
import smecta.client.print.mapper.SysReportMapper;
import smecta.client.print.service.ScpCodeFormService;
import smecta.client.print.service.ScpDataAcqService;
import smecta.client.print.service.ScpPackageService;
import smecta.client.print.util.AlertUtil;
import smecta.client.print.util.OSUtil;

import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ReportController {

    @Autowired
    private SysReportMapper sysReportMapper;

    @FXML
    private DatePicker startDatePicker;

    @FXML
    private DatePicker endDatePicker;

    @FXML
    private TextField creatorTextField;

    @FXML
    private ToggleGroup sortToggleGroup;

    @FXML
    private RadioButton sortBySpecRadioButton;

    @FXML
    private RadioButton sortByBatchNumberRadioButton;

    @FXML
    private RadioButton sortByGradeRadioButton;

    @FXML
    private TableView<ScpDataAcqModel> reportTableView;

    @FXML
    private TableColumn<ScpDataAcqModel, Long> id;

    @FXML
    private TableColumn<ScpDataAcqModel, String> type;

    @FXML
    private TableColumn<ScpDataAcqModel, String> batchNumber;

    @FXML
    private TableColumn<ScpDataAcqModel, String> spec;

    @FXML
    private TableColumn<ScpDataAcqModel, String> grade;

    @FXML
    private TableColumn<ScpDataAcqModel, Integer> boxNumber;

    @FXML
    private TableColumn<ScpDataAcqModel, Integer> quantity;

    @FXML
    private TableColumn<ScpDataAcqModel, BigDecimal> grossWeight;

    @FXML
    private TableColumn<ScpDataAcqModel, BigDecimal> netWeight;

    @FXML
    private Button sumButton;

    @FXML
    private Button queryButton;

    @FXML
    private Button printButton;

    @FXML
    private Button exportButton;

    @FXML
    private Button closeButton;
    @Autowired
    private ScpDataAcqService scpDataAcqService;
    @Autowired
    private ScpPackageService scpPackageService;
    @Autowired
    private ScpCodeFormService scpCodeFormService;

    @FXML
    private void initialize() {
        // 为每个TableColumn设置cell value factory
        type.setCellValueFactory(new PropertyValueFactory<>("pinming"));
        batchNumber.setCellValueFactory(new PropertyValueFactory<>("pihao"));
        spec.setCellValueFactory(new PropertyValueFactory<>("guige"));
        grade.setCellValueFactory(new PropertyValueFactory<>("levelName"));
        boxNumber.setCellValueFactory(new PropertyValueFactory<>("boxNum"));
        quantity.setCellValueFactory(new PropertyValueFactory<>("canNum"));
        grossWeight.setCellValueFactory(new PropertyValueFactory<>("grossWeight"));
        netWeight.setCellValueFactory(new PropertyValueFactory<>("netWeight"));

        handleQuery();
    }

    @FXML
    private void handleSum() {
        // 处理合计逻辑
        System.out.println("合计");
        ObservableList<ScpDataAcqModel> items = reportTableView.getItems();
//        Integer sumCanNum = items.stream().collect(Collectors.summingInt(ScpDataAcqModel::getCanNum));
        Integer sumCanNum = 0;
        Integer sumBoxNum = 0;
        BigDecimal sumGrossWeight = BigDecimal.ZERO;
        BigDecimal sumNetWeight = BigDecimal.ZERO;

        for (ScpDataAcqModel item : items) {
            // TODO  这边有个问题，显示的是箱号 并不是 箱数（箱的数量） 逻辑还需要再理一下
            sumBoxNum += item.getBoxNum();
            sumCanNum += item.getCanNum();
            sumGrossWeight = sumGrossWeight.add(item.getGrossWeight());
            sumNetWeight = sumNetWeight.add(item.getNetWeight());
        }

        // 将合计行添加到表格数据中，并刷新表格视图
        ScpDataAcqModel sumModel = new ScpDataAcqModel();
        sumModel.setPinming("合计：");
        sumModel.setBoxNum(sumBoxNum);
        sumModel.setCanNum(sumCanNum);
        sumModel.setGrossWeight(sumGrossWeight);
        sumModel.setNetWeight(sumNetWeight);
        items.add(sumModel);
        reportTableView.refresh();
    }

    //假设 RowData 是您的数据模型类
    class RowData {
        public RowData(int id, String type, String batchNumber, String spec, String grade, String boxNumber, String quantity, String grossWeight, String netWeight) {
            // TODO Auto-generated constructor stub
        }

        private final SimpleStringProperty type = new SimpleStringProperty();
        private final SimpleStringProperty batchNumber = new SimpleStringProperty();
        private final SimpleStringProperty spec = new SimpleStringProperty();
        private final SimpleStringProperty grade = new SimpleStringProperty();
        private final SimpleStringProperty boxNumber = new SimpleStringProperty();
        private final SimpleStringProperty quantity = new SimpleStringProperty();
        private final SimpleStringProperty grossWeight = new SimpleStringProperty();
        private final SimpleStringProperty netWeight = new SimpleStringProperty();

        // 构造函数、getter 和 setter 省略
    }

    @FXML
    private void handlePrint() {
        try {
            PrinterJob printerJob = PrinterJob.createPrinterJob();
            String defaultPrinterName = "Microsoft Print to PDF";
            if (!defaultPrinterName.isEmpty()) {
                System.out.println("defaultPrinterName:" + defaultPrinterName);
                Printer defaultPrinter = Printer.getAllPrinters().stream()
                        .filter(printer -> printer.getName().equals(defaultPrinterName))
                        .findFirst()
                        .orElse(null);
                System.out.println("defaultPrinter:" + defaultPrinter);
                if (defaultPrinter != null) {
                    printerJob.setPrinter(defaultPrinter);
                }
            }

            System.out.println(printerJob.showPrintDialog(printButton.getScene().getWindow()));
            if (printerJob != null && printerJob.showPrintDialog(printButton.getScene().getWindow())) {
                // 这里可以添加需要打印的内容
                System.out.println("用户已确认打印设置");
                printerJob.printPage(reportTableView);
                // 假设打印成功
                boolean success = printerJob.endJob();
                if (success) {
                    System.out.println("打印任务已完成");
                } else {
                    System.out.println("打印任务未能完成");
                }
            } else {
                System.out.println("用户取消了打印设置");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void handleExport() {
        // 处理导出逻辑
        // 获取表格中的所有数据
        ObservableList<ScpDataAcqModel> items = reportTableView.getItems();

        // 定义CSV文件的路径
        String csvFilePath = String.format("%s/report_data_%s.csv", OSUtil.getDesktopPath(), System.currentTimeMillis());

        try (FileWriter writer = new FileWriter(csvFilePath)) {
            // 写入表头
            writer.append("Type");
            writer.append(",");
            writer.append("Batch Number");
            writer.append(",");
            writer.append("Specification");
            writer.append(",");
            writer.append("Grade");
            writer.append(",");
            writer.append("Box Number");
            writer.append(",");
            writer.append("Quantity");
            writer.append(",");
            writer.append("Gross Weight");
            writer.append(",");
            writer.append("Net Weight");
            writer.append("\n");

            // 写入数据行
            for (ScpDataAcqModel item : items) {
                writer.append(item.getPinming());
                writer.append(",");
                writer.append(item.getPihao());
                writer.append(",");
                writer.append(item.getGuige());
                writer.append(",");
                writer.append(item.getLevelName());
                writer.append(",");
                writer.append(String.valueOf(item.getBoxNum()));
                writer.append(",");
                writer.append(String.valueOf(item.getCanNum()));
                writer.append(",");
                writer.append(String.valueOf(item.getGrossWeight()));
                writer.append(",");
                writer.append(String.valueOf(item.getNetWeight()));
                writer.append("\n");
            }

            // 提示导出成功
            AlertUtil.info(String.format("导出成功,文件访问路径是:%s",csvFilePath));
        } catch (IOException e) {
            // 处理异常
            log.error("handleExport error:{}", e);
            AlertUtil.error(String.format("导出失败,失败原因:%s",e.getMessage()));
        }
    }

    @FXML
    private void handleClose() {
        // 关闭窗口
        Stage stage = (Stage) closeButton.getScene().getWindow();
        stage.close();
    }

    @FXML
    private void handleSortBySpec() {
        // 处理按规格排序逻辑
        System.out.println("按规格排序");
    }

    @FXML
    private void handleSortByBatchNumber() {
        // 处理按批号排序逻辑
        System.out.println("按批号排序");
    }

    @FXML
    private void handleSortByGrade() {
        // 处理按等级排序逻辑
        System.out.println("按等级排序");
    }

    List<RowData> rowsList = new ArrayList<>();

    @FXML
    private void handleQuery() {
        // 清空旧数据
        reportTableView.getItems().clear();

        LocalDate startDate = startDatePicker.getValue();
        LocalDate endDate = endDatePicker.getValue();
        String person = creatorTextField.getText();

        List<ScpCodeFormModel> allListByStatus = scpCodeFormService.getAllListByStatus(0);
        List<String> codeNumFirldList = allListByStatus.stream().map(ScpCodeFormModel::getCodeNum)
                .distinct()
                .collect(Collectors.toList());

        ReportQuery reportQuery = new ReportQuery();
        if (startDate != null){
            reportQuery.setStartDay(startDate.toString());
        }
        if (endDate != null){
            reportQuery.setEndDay(endDate.toString());
        }
        reportQuery.setPerson(person);
        // 分页的第几页
        Integer pageNo = 1;
        // 每页的数据数
        Integer pageSize = 10000;
        reportQuery.setPageNo(pageNo);
        reportQuery.setPageSize(pageSize);
        PageDTO<ScpDataAcqModel> page = scpDataAcqService.page(reportQuery,codeNumFirldList);
        List<ScpDataAcqModel> list = page.getList();
        // 填充数据
        if (CollectionUtils.isNotEmpty(list)){
            List<Long> produceIdList = list.stream().map(ScpDataAcqModel::getProduceId).distinct().collect(Collectors.toList());
            List<ScpPackage> packageList = scpPackageService.getListByIdList(produceIdList);
            Map<Long, ScpPackage> map = packageList.stream().collect(Collectors.toMap(ScpPackage::getId, Function.identity()));
            for (ScpDataAcqModel scpDataAcqModel : list) {
                Long produceId = scpDataAcqModel.getProduceId();
                ScpPackage scpPackage = map.getOrDefault(produceId, null);
                if (scpPackage != null){
                    scpDataAcqModel.setPinming(scpPackage.getPinming());
                    scpDataAcqModel.setPihao(scpPackage.getPihao());
                    scpDataAcqModel.setGuige(scpPackage.getGuige());
                }
            }
            reportTableView.getItems().addAll(page.getList());
        }

        reportTableView.refresh();
    }
}